package com.payment.controller.paynotify;

import com.alibaba.fastjson.JSON;
import com.payment.entity.common.UserOrderPackage;
import com.payment.entity.payresults.paypal.*;
import com.payment.entity.purchase.response.ResponsePurchaseService;
import com.payment.service.NotificationpaymentService;
import com.payment.service.PartnerService;
import com.payment.service.UserOrderPackageService;
import com.payment.service.impl.CommonUtilsServiceImpl;
import com.payment.utils.Constant;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(description = "paypal支付回调")
/**
 * 1，使用领科的paypal收款账号收款，paypal支付回调接口：
 *
 * 2，适用于新的客户：最新版的的领科 H5 和其他想要使用领科paypal收款接口,收款的（可以是客户自己的账号或者领科发账号）客户；
 *
 * 3，更新的数据表为：user_order_package_t，user_order_payment_t；
 *
 *  4，更新的数据库为：v-shop
 *
 * @author lm
 * @date 2019/11/06
 */
public class NotifyPaypalController {

    private static Logger logger = Logger.getLogger(NotifyPaypalController.class);

    @Autowired
    private NotificationpaymentService notificationpaymentService;

    @Autowired
    private PartnerService partnerService;

    @Autowired
    private UserOrderPackageService orderService;

    @Autowired
    private CommonUtilsServiceImpl utilsService;

    private String reStatus = "Completed";

    /***
     * 此方法专门处理paypal的ipn回调
     * @return
     * @throws Exception
     */

    //@PostMapping(value = "ipn")
    @PostMapping(value = "payPalIpn")
    @CrossOrigin
    public void ipn(@RequestBody String reStr) {

        logger.info("paypal的ipn回调:" + reStr);

        if (null != reStr && !reStr.equalsIgnoreCase("null") && StringUtils.isNotBlank(reStr)) {

            try {
                String[] outerSplit = reStr.split("&");
                Map<String, String> m = new HashMap<String, String>();

                for (int i = 0; i < outerSplit.length; i++) {

                    if (outerSplit[i].split("=").length == 1) {
                        outerSplit[i] = outerSplit[i] + "00";
                    }
                    String[] innerSplit = outerSplit[i].split("=");

                    m.put(innerSplit[0], URLDecoder.decode(innerSplit[1], "UTF-8"));
                }
                logger.info("ipn转成map:" + m);

                if (StringUtils.isNotBlank(m.get("invoice") + "") && StringUtils.isNotBlank(m.get("mc_gross") + "") && StringUtils.isNotBlank(m.get("payment_status") + "")) {

                    logger.info("收款账号是：" + m.get("business") + ";收款金额：" + m.get("mc_gross") + "付款状态是：" + m.get("payment_status") + ";付款订单：" + m.get("invoice"));

                    String status = m.get("payment_status") + "";
                    String payId = m.get("invoice") + "";
                    //查询payId在数据库有几条记录
                    int payIdCount = 1;
                    if (orderService.findPayIdCount(payId) <= 0) {
                        payIdCount = 1;
                    } else {
                        payIdCount = orderService.findPayIdCount(payId);
                    }
                    //单价
                    float fee = Float.parseFloat(m.get("mc_gross") + "") / payIdCount;
                    //总价
                    float fee1 = Float.parseFloat(m.get("mc_gross") + "");

                    //支付的总金额相当于付款时的金额
                    String payAmount = String.format("%1.2f", fee1);

                    //支付的总金额/订单条数=每笔订单支付的单价
                    String payUnit = String.format("%1.2f", fee);

                    String settlePrice = "";
                    if (fee <= 0.01) {
                        settlePrice = "0.00";
                    } else {
                        settlePrice = String.format("%1.2f", fee);
                    }

                    //查询订单数据表中此条记录有没有入过库
                    int orderCount = orderService.findPayIdByNotify(payId);

                    if (orderCount <= 0) {

                        if (reStatus.equalsIgnoreCase(status)) {

                            // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
                            Integer count = utilsService.updatePayRst(payId, payUnit, m.get("mc_currency") + "", settlePrice, m.get("txn_id") + "", Constant.PAY_PAYPAL, "success", "1", "2");

                            if (count <= 0) {
                                //说明订单可能已经移到user_order_package_hist_t去了，我们把结果先插入到user_order_package_hist_t去，然后再写一条记录到user_order_package_t表
                                Integer co = utilsService.updatePayRstForHist(payId, payUnit, m.get("mc_currency") + "", settlePrice, m.get("txn_id") + "", Constant.PAY_PAYPAL, "success", "1", "2");

                                //成功的回调数据入库：根据支付id和金额入库：user_order_payment_hist_t
                                utilsService.updatePaymentForHist(payId, payAmount, m.get("mc_currency") + "", m.get("txn_id") + "", Constant.PAY_PAYPAL, "success");

                                if (co > 0) {
                                    //将user_order_package_hist_t中订单的记录写入到user_order_package_t去
                                    List<UserOrderPackage> orderList = orderService.queryOrderList(payId);

                                    for (UserOrderPackage o : orderList) {

                                        Integer countOrder = utilsService.insertOrderToOrderT(
                                                o.getPartnerCode(), o.getPartnerName(),
                                                o.getDeviceCode(), o.getIccId(),
                                                o.getPackageCode(), o.getPackageName(), o.getPackageType(),
                                                o.getBuyType(), o.getPriceType(), o.getSalesType(), o.getGlobalOrder(),
                                                o.getOrderPeriod(), o.getRequestOrderId(), o.getOrderNo(), o.getOrderId(), o.getPayId(),
                                                o.getPayAmount(), o.getPayCurrency(), o.getSettlePrice(),
                                                o.getPartnerScope(),
                                                o.getPackageFee(), o.getExpressFee(), o.getCardFee(),
                                                o.getOrderStatus(), o.getPayType(), o.getPayRst(),
                                                o.getIsNotify(), o.getPayAccount(), o.getTransactionId(), o.getCreateDate());

                                        Integer countPayment = utilsService.insertOrderToPaymentT(o.getPartnerCode(), o.getRequestOrderId(), o.getPayId(), o.getTransactionId(), payAmount, o.getPayCurrency(), o.getPayType(), o.getPayRst());

                                        if (countOrder > 1 && countPayment > 1) {
                                            logger.info(o.getPayId() + "：捞起成功");
                                        }
                                    }

                                }

                            }

                            //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                            utilsService.updatePaymentRst(payId, payAmount, m.get("mc_currency") + "", m.get("txn_id") + "", Constant.PAY_PAYPAL, "success");

                            //成功无卡订单支付结果入库：user_nocard_order_t
                            utilsService.updateNoCardPayRst(payId, "success");

                            //支付成功：才考虑入库那些问题
                            logger.info("订单是完成状态:" + m.get("payment_status") + ";订单" + payId + "支付结果更新成功");

                            //现在拿到支付的结果了，可以去做订购套餐的操作了
                            List<UserOrderPackage> userOrderList = orderService.queryOrderByPayIdAndAmount(payId, m.get("mc_gross") + "");

                            if (null != userOrderList && userOrderList.size() > 0 && !userOrderList.isEmpty()) {

                                for (UserOrderPackage u : userOrderList) {

                                    if (StringUtils.isNotBlank(u.getPartnerCode())) {

                                        String secret = partnerService.findSecretByPartnerCode(u.getPartnerCode());

                                        if (StringUtils.isNotBlank(secret) && StringUtils.isNotBlank(u.getDeviceCode()) && StringUtils.isNotBlank(u.getPackageName()) && StringUtils.isNotBlank(u.getPackageCode()) &&
                                                StringUtils.isNotBlank(u.getPackageType()) && StringUtils.isNotBlank(u.getOrderPeriod()) && StringUtils.isNotBlank(u.getPayAmount()) && StringUtils.isNotBlank(u.getPayId()) &&
                                                "success".equalsIgnoreCase(u.getPayRst())) {

                                            logger.info(u.getDeviceCode() + "：符合【订购套餐】条件，现在去请求");

                                            //符合要求就去请求订购套餐
                                            ResponsePurchaseService re = utilsService.purchase(u.getPartnerCode(), secret, u.getDeviceCode(), u.getPackageName(), u.getPackageCode(), u.getPackageType(),
                                                    u.getOrderPeriod(), u.getPayAmount(), u.getBuyType(), u.getPriceType(), u.getSalesType(), u.getPayId(), u.getOrderNo(), u.getPayRst(), Constant.PAY_PAYPAL);

                                            if (null != re && true == Constant.RET_CODE_0000.equals(re.getRetCode())) {

                                                logger.info("【订购套餐】成功");
                                            } else {
                                                logger.info("【订购套餐】失败");
                                            }
                                        } else {
                                            logger.info("查询到了订单但是主要的订购所需的参数有为空，进入异常处理");
                                        }

                                    } else {
                                        logger.info("查询到了订单但是partnerCode为空，进入异常处理");
                                    }

                                }

                            } else {
                                logger.info("数据库不存在此订单");
                            }

                        } else {

                            // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
                            utilsService.updatePayRst(payId, payUnit, m.get("mc_currency") + "", settlePrice, m.get("txn_id") + "", Constant.PAY_PAYPAL, "fail", "0", "2");

                            //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                            utilsService.updatePaymentRst(payId, payAmount, m.get("mc_currency") + "", m.get("txn_id") + "", Constant.PAY_PAYPAL, "fail");

                            //成功无卡订单支付结果入库：user_nocard_order_t
                            utilsService.updateNoCardPayRst(payId, "fail");
                            //订单状态不是完成的状态
                            logger.info("订单非完成状态:" + payAmount + ";订单" + payId + "支付结果更新成功");
                        }
                    } else {
                        logger.info(payId + "：已入库过支付结果！");
                    }

                    //为了把paypal申诉退款的记录全部记下：
                    if (!reStatus.equalsIgnoreCase(status)) {

                        //入库paypal申诉退款记录
                        utilsService.insertPaypalReversed(m.get("mc_gross"), m.get("invoice"), m.get("payment_status"), m.get("mc_currency"), m.get("txn_id"), m.get("protection_eligibility"),
                                m.get("address_status"), m.get("payer_id"), m.get("address_street"), m.get("payment_date"), m.get("charset"), m.get("address_zip"), m.get("first_name"), m.get("mc_fee"),
                                m.get("address_country_code"), m.get("address_name"), m.get("notify_version"), m.get("custom"), m.get("payer_status"), m.get("business"), m.get("address_country"), m.get("address_city"),
                                m.get("quantity"), m.get("verify_sign"), m.get("payer_email"), m.get("payment_type"), m.get("last_name"), m.get("address_state"), m.get("receiver_email"), m.get("payment_fee"),
                                m.get("receiver_id"), m.get("txn_type"), m.get("item_name"), m.get("item_number"), m.get("residence_country"), m.get("receipt_id"), m.get("transaction_subject"),
                                m.get("payment_gross"), m.get("ipn_track_id"));
                    }


                    //最后再做这一步操作将paypal回传的交易记录入库保存下来:notification_payment_results_paypal_t
                    int c = notificationpaymentService.findCountByOrderNumber(payId);

                    if (c <= 0) {

                        //入库微信流水记录
                        utilsService.insertPaypalIpnResults(m.get("mc_gross"), m.get("invoice"), m.get("payment_status"), m.get("mc_currency"), m.get("txn_id"), m.get("protection_eligibility"),
                                m.get("address_status"), m.get("payer_id"), m.get("address_street"), m.get("payment_date"), m.get("charset"), m.get("address_zip"), m.get("first_name"), m.get("mc_fee"),
                                m.get("address_country_code"), m.get("address_name"), m.get("notify_version"), m.get("custom"), m.get("payer_status"), m.get("business"), m.get("address_country"), m.get("address_city"),
                                m.get("quantity"), m.get("verify_sign"), m.get("payer_email"), m.get("payment_type"), m.get("last_name"), m.get("address_state"), m.get("receiver_email"), m.get("payment_fee"),
                                m.get("receiver_id"), m.get("txn_type"), m.get("item_name"), m.get("item_number"), m.get("residence_country"), m.get("receipt_id"), m.get("transaction_subject"),
                                m.get("payment_gross"), m.get("ipn_track_id"));
                    }

                } else {
                    logger.info("ipn回调的主要数据有问题");
                }
            } catch (Exception e) {

                logger.info("ipn回调处理异常：" + e);

            }
        } else {
            logger.info("ipn回调内容为空");
        }

    }

    /****
     * 此方法专门处理paypal的webhook回调
     * @param reStr
     * @return
     * @throws Exception
     */

    @PostMapping(value = "notifyWebhook")
    @CrossOrigin
    public void webhook(@RequestBody String reStr) {

        logger.info("paypal的webhook回调:" + reStr);

        if (StringUtils.isNotBlank(reStr)) {
            try {
                JsonRootBean jsonRootBean = JSON.parseObject(reStr, JsonRootBean.class);

                if (null == jsonRootBean) {
                    logger.info("请求jsonRootBean参数为null");
                } else {
                    if (null == jsonRootBean.getResource()) {
                        logger.info("请求jsonRootBean参数为null");
                    } else {
                        Resource resource = jsonRootBean.getResource();
                        if (StringUtils.isNotBlank(resource.getInvoice_number()) && StringUtils.isNotBlank(resource.getState()) && StringUtils.isNotBlank(resource.getParent_payment())) {
                            //Resource
                            String payId = resource.getInvoice_number();
                            String state = resource.getState();
                            String parent_payment = resource.getParent_payment();
                            String id = resource.getId();
                            String payment_mode = resource.getPayment_mode();
                            String protection_eligibility = resource.getProtection_eligibility();
                            String protection_eligibility_type = resource.getProtection_eligibility_type();

                            if (null == resource.getAmount()) {
                                logger.info("请求amount参数为null");
                            } else {
                                //Amount
                                Amount amount = resource.getAmount();
                                if (null == amount.getDetails() || StringUtils.isBlank(amount.getTotal()) || StringUtils.isBlank(amount.getCurrency())) {
                                    logger.info("请求details参数为null或者价格为空");
                                } else {
                                    //金额
                                    String total = amount.getTotal();
                                    String currency = amount.getCurrency();
                                    //查询payId在数据库有几条记录
                                    int payIdCount = 1;
                                    if (orderService.findPayIdCount(payId) <= 0) {
                                        payIdCount = 1;
                                    } else {
                                        payIdCount = orderService.findPayIdCount(payId);
                                    }

                                    //单价
                                    float fee = Float.parseFloat(total) / payIdCount;
                                    //总价
                                    float fee1 = Float.parseFloat(total);

                                    //支付的总金额相当于付款时的金额
                                    String payAmount = String.format("%1.2f", fee1);

                                    //支付的总金额/订单条数=每笔订单支付的单价
                                    String payUnit = String.format("%1.2f", fee);

                                    String settlePrice = "";
                                    if (fee <= 0.01) {
                                        settlePrice = "0.00";
                                    } else {
                                        settlePrice = String.format("%1.2f", fee);
                                    }

                                    if (null == resource.getTransaction_fee()) {
                                        logger.info("请求transaction_fee参数为null");
                                    } else {
                                        //Details
                                        Details details = amount.getDetails();
                                        String subtotal = details.getSubtotal();

                                        //Transaction_fee
                                        Transaction_fee transaction_fee = resource.getTransaction_fee();

                                        String value = transaction_fee.getValue();
                                        String currencys = transaction_fee.getCurrency();

                                        //除去测试的数据不用入库
                                        if (!payId.substring(0, 2).equalsIgnoreCase("WC")) {

                                            //支付成功
                                            if (reStatus.equalsIgnoreCase(state)) {

                                                // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
                                                Integer count = utilsService.updatePayRst(payId, payUnit, currency, settlePrice, id, Constant.PAY_PAYPAL, "success", "1", "2");

                                                if (count <= 0) {
                                                    //说明订单可能已经移到user_order_package_hist_t去了，我们把结果先插入到user_order_package_hist_t去，然后再写一条记录到user_order_package_t表
                                                    Integer co = utilsService.updatePayRstForHist(payId, payUnit, currency, settlePrice, id, Constant.PAY_PAYPAL, "success", "1", "2");

                                                    //成功的回调数据入库：根据支付id和金额入库：user_order_payment_hist_t
                                                    utilsService.updatePaymentForHist(payId, payAmount, currency, id, Constant.PAY_PAYPAL, "success");

                                                    if (co > 0) {
                                                        //将user_order_package_hist_t中订单的记录写入到user_order_package_t去

                                                        List<UserOrderPackage> orderList = orderService.queryOrderList(payId);

                                                        for (UserOrderPackage o : orderList) {

                                                            Integer c1 = utilsService.insertOrderToOrderT(o.getPartnerCode(), o.getPartnerName(), o.getDeviceCode(), o.getIccId(), o.getPackageCode(), o.getPackageName(), o.getPackageType(),
                                                                    o.getBuyType(), o.getPriceType(), o.getSalesType(), o.getGlobalOrder(), o.getOrderPeriod(), o.getRequestOrderId(), o.getOrderNo(), o.getOrderId(), o.getPayId(),
                                                                    o.getPayAmount(), o.getPayCurrency(), o.getSettlePrice(), o.getPartnerScope(), o.getPackageFee(), o.getExpressFee(), o.getCardFee(), o.getOrderStatus(), o.getPayType(), o.getPayRst(),
                                                                    o.getIsNotify(), o.getPayAccount(), o.getTransactionId(), o.getCreateDate());

                                                            Integer c2 = utilsService.insertOrderToPaymentT(o.getPartnerCode(), o.getRequestOrderId(), o.getPayId(), o.getTransactionId(), total, o.getPayCurrency(), o.getPayType(), o.getPayRst());
                                                            if (c1 > 1) {
                                                                logger.info(o.getPayId() + "：捞起成功");
                                                            }
                                                        }

                                                    }

                                                }

                                                //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                                                utilsService.updatePaymentRst(payId, payAmount, currency, id, Constant.PAY_PAYPAL, "success");

                                                //成功无卡订单支付结果入库：user_nocard_order_t
                                                utilsService.updateNoCardPayRst(payId, "success");

                                                //支付成功：才考虑入库那些问题
                                                logger.info("订单是完成状态:" + state + ";订单" + payId + "支付结果更新成功");

                                                //现在拿到支付的结果了，可以去做订购套餐的操作了
                                                List<UserOrderPackage> userOrderList = orderService.queryOrderByPayIdAndAmount(payId, total);

                                                if (null != userOrderList && userOrderList.size() > 0 && !userOrderList.isEmpty()) {

                                                    for (UserOrderPackage u : userOrderList) {

                                                        if (StringUtils.isNotBlank(u.getPartnerCode())) {

                                                            String secret = partnerService.findSecretByPartnerCode(u.getPartnerCode());

                                                            if (StringUtils.isNotBlank(secret) && StringUtils.isNotBlank(u.getDeviceCode()) && StringUtils.isNotBlank(u.getPackageName()) && StringUtils.isNotBlank(u.getPackageCode()) &&
                                                                    StringUtils.isNotBlank(u.getPackageType()) && StringUtils.isNotBlank(u.getOrderPeriod()) && StringUtils.isNotBlank(u.getPayAmount()) && StringUtils.isNotBlank(u.getPayId()) &&
                                                                    "success".equalsIgnoreCase(u.getPayRst())) {

                                                                logger.info(u.getDeviceCode() + "：符合【订购套餐】条件，现在去请求");

                                                                //符合要求就去请求订购套餐
                                                                ResponsePurchaseService re = utilsService.purchase(u.getPartnerCode(), secret, u.getDeviceCode(), u.getPackageName(), u.getPackageCode(), u.getPackageType(),
                                                                        u.getOrderPeriod(), u.getPayAmount(), u.getBuyType(), u.getPriceType(), u.getSalesType(), u.getPayId(), u.getOrderNo(), u.getPayRst(), Constant.PAY_PAYPAL);

                                                                if (null != re && true == Constant.RET_CODE_0000.equals(re.getRetCode())) {

                                                                    logger.info("【订购套餐】成功");
                                                                } else {
                                                                    logger.info("【订购套餐】失败");
                                                                }
                                                            } else {
                                                                logger.info("查询到订单但主要订购所需参数有为空");
                                                            }

                                                        } else {
                                                            logger.info("查询到订单但partnerCode为空");
                                                        }

                                                    }

                                                } else {
                                                    logger.info("订单查询有误！");
                                                }

                                            } else {
                                                logger.info("订单非完成状态:" + state);
                                                // 成功的回调数据入库：根据支付id和金额入库：user_order_package_t
                                                utilsService.updatePayRst(payId, payUnit, currency, settlePrice, id, Constant.PAY_PAYPAL, "fail", "0", "2");

                                                //成功的回调数据入库：根据支付id和金额入库：user_order_payment_t
                                                utilsService.updatePaymentRst(payId, payAmount, currency, id, Constant.PAY_PAYPAL, "fail");

                                                //成功无卡订单支付结果入库：user_nocard_order_t
                                                utilsService.updateNoCardPayRst(payId, "fail");
                                                //订单状态不是完成的状态
                                                logger.info("订单非完成状态:" + state + ";订单" + payId + "支付结果更新成功");
                                            }

                                        }
                                        //最后一步再去入库充值流水记录：
                                        int c = notificationpaymentService.findCountByInvoiceNumber(payId);
                                        if (c <= 0) {
                                            utilsService.insertPaypalWebhookResults(id, state, payId, payment_mode, protection_eligibility, protection_eligibility_type, parent_payment, total, currency, subtotal, value, currencys);
                                        }
                                    }
                                }
                            }
                        } else {
                            //回调的主要参数为空
                            logger.info("回调的主要参数为空");
                        }
                    }
                }

            } catch (Exception e) {
                logger.info("ipn回调reStr转码失败：" + e);
            }
        } else {
            logger.info("paypal的webhook回调为null");
        }
    }

}




